package puyu.manage.service.security.service;



import cn.hutool.core.util.ObjectUtil;
import puyu.manage.service.SysUser.dao.SysUserMapper;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import puyu.manage.service.common.dao.CommonMapper;
import puyu.manage.service.constant.Constants;
import puyu.manage.service.utils.MessageUtils;
import puyu.manage.service.utils.StringUtils;
import puyu.manage.service.utils.except.BaseException;
import puyu.manage.service.utils.except.CustomException;
import puyu.manage.service.utils.redis.RedisCache;
import puyu.manage.service.utils.redis.RedisUtil;

import java.util.HashMap;
import java.util.Map;

import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

@Component
public class WebLogin extends DefaultCommonLogin {

    @Autowired(required = false)
    private SysUserMapper sysUserMapper;

    @Autowired(required = false)
    private AuthenticationManager authenticationManager;

    @Autowired(required = false)
    private RedisCache redisCache;
    @Autowired(required = false)
    private RedisUtil redisUtil;

    @Autowired(required = false)
    private CommonMapper commonMapper;

    public static final String NUMBER_0 = "0";

    @Override
    public Map<String, Object> login(Map<String, Object> params) {
        String userName = params.get("userName")+"";
        String passWord = params.get("password")+"";

        Integer loginNum = redisCache.getCacheObject(userName);
        //loginDomain.setLoginNum(loginNum);
        // 密码复杂度验证
        Map<String, Object> sysUser = sysUserMapper.selectUserInfoByUserName(userName);
        if (sysUser == null) {
            throw new BaseException(MessageUtils.message("A0100",userName));
        }
        if (Constants.NO.equals(sysUser.get("status"))) {//停用
            throw new BaseException(MessageUtils.message("A0103"));
        }
        if ("2".equals(sysUser.get("status"))) {//锁定
            throw new BaseException(MessageUtils.message("A0102"));
        }
//        if (pwdType(password, codeRule)) {
//            if (SecurityUtils.matchesPassword(password, sysUser.getPassword())) {
//                map.put("token", Constants.SUCCESS);
//                return map;
//            }
//        }
        //用户验证
        Authentication authentication = null;
        Map<String, Object> map = new HashMap<>(3);
            map = authentication(authentication, userName, passWord, loginNum);
        if (loginNum != null && loginNum >= 5) {
            long expire = redisUtil.getExpire(userName);
            throw new BaseException(MessageUtils.message("A0113", userName, expire));
        }
        redisCache.deleteObject(userName);

        //登陆超时
        Map<String, Object> overTimeMap = loginOverTime((Authentication) map.get("authentication"), userName,
                Constants.WEB);
        if (MapUtils.isNotEmpty(overTimeMap)) {
            map.putAll(overTimeMap);
        }

        //修改用户的登录时间
        commonMapper.executeSql("update sys_t_user set login_date=SYSDATE() where user_name= '"+userName+"'");
        return map;
    }

    @Override
    public Map<String, Object> authentication(Authentication authentication, String username, String password, Integer loginNum) {
        Map<String, Object> map = new HashMap<>();
        // 用户验证
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
            map.put("authentication", authentication);
            return map;
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                // 根据条件锁定账户
                loginNum = loginNum == null ? 1 : loginNum + 1;
                if (loginNum >= 1 && loginNum < 3) {
                    redisCache.setCacheObject(username, loginNum);
                }
                if (loginNum >= 3 && loginNum < 5) {
                    redisCache.setCacheObject(username, loginNum);
                }
                if (loginNum == 5) {
                    redisCache.setCacheObject(username, loginNum, 5, SECONDS);
                    throw new BaseException(MessageUtils.message("A0113", username, 5));
                }
                if (loginNum > 5) {
                    long expire = redisUtil.getExpire(username);
                    throw new BaseException(MessageUtils.message("A0113", username, expire));
                }
                throw new BaseException(MessageUtils.message("A0125", username));
            } else {
                throw new CustomException(e.getMessage());
            }
        }

    }


}
